package com.yeyks.commonReference.service.account.impl;

import com.yeyks.common.dto.AccountCardDTO;
import com.yeyks.common.em.card.MemberCardTypeEnum;
import com.yeyks.common.em.vip.HotelDeveloperRelationTypeEnum;
import com.yeyks.common.em.vip.MiniVipCommissionBillTypeEnum;
import com.yeyks.common.em.vip.VipCommissionBillTypeEnum;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.utils.FormatUtils;
import com.yeyks.commonReference.service.account.AccountCommissionService;
import com.yeyks.commonReference.service.consumer.MemberCardService;
import com.yeyks.commonReference.service.hotel.HotelDeveloperRelationService;
import com.yeyks.commonReference.service.hotel.HotelInfoService;
import com.yeyks.commonReference.service.vip.MiniVipCommissionBillService;
import com.yeyks.consumer.dal.domain.MemberCard;
import com.yeyks.hotel.dal.domain.HotelDeveloperRelation;
import com.yeyks.order.dal.domain.OrderHead;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author shuai
 * @date 2019/12/12 13:59
 */
@Service
@Slf4j
public class AccountCommissionServiceImpl implements AccountCommissionService {

    @Autowired
    private MemberCardService memberCardService;
    @Autowired
    private HotelDeveloperRelationService hotelDeveloperRelationService;
    @Autowired
    private MiniVipCommissionBillService miniVipCommissionBillService;
    @Autowired
    private HotelInfoService hotelInfoService;

    /**
     * 精选酒店发佣金
     *
     * @param orderHead
     */
    @Override
    public void setMiniVipCommission(OrderHead orderHead) {
        long time = System.currentTimeMillis();
        log.info("小Vip佣金入账开始......");
        try {
            //1 查询出卡对应的酒店账户id和卡号以及卖卡人类型(0运营商或者2卡商)
            AccountCardDTO accountCardDTO = memberCardService.selectOperatorIdAndCardNoByUserId(orderHead.getUserId(), MemberCardTypeEnum.MINI_VIP.value());
            if (null == accountCardDTO || null == accountCardDTO.getCardNo()) {
                log.info("查询到的酒店账户id或者订单对应卡号为空orderNo = {}", orderHead.getOrderNo());
                return;
            }
            //是否是运营商卖的卡
            Boolean flag = 0 == accountCardDTO.getSalerType();
            //2 卡酒店(会员卡对应酒店账户id)和卡运营商发放佣金
            miniDisposeCommission(orderHead, accountCardDTO.getAccountId(), accountCardDTO.getCardNo(), accountCardDTO.getPhone(), 1, flag);
            //3 非卡酒店(订单中酒店账户id)和非卡运营商发放佣金
            Integer noCardHotelAccountId = hotelInfoService.selectOperatorIdByHotelId(orderHead.getHotelId());
            miniDisposeCommission(orderHead, noCardHotelAccountId, accountCardDTO.getCardNo(), accountCardDTO.getPhone(), 2, flag);
            //4 卡商为运营商不分佣金
            MemberCard memberCard = memberCardService.selectByCardNoAndType(accountCardDTO.getCardNo(), 2, 2);
            if (null != memberCard && null != memberCard.getSalerId()) {
                miniAddCommission(orderHead, memberCard.getSalerId(), accountCardDTO.getCardNo(), accountCardDTO.getPhone(), VipCommissionBillTypeEnum.CARD_VIP.value(), flag);
            }
        } catch (ServiceException e) {
            log.info("小vip分佣异常订单号orderNo = {}", orderHead.getOrderNo());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("小vip分佣异常订单号orderNo = {}", orderHead.getOrderNo());
        }
        log.info("小Vip佣金入账结束，总耗时{}毫秒", System.currentTimeMillis() - time);
    }

    /**
     * 小vip处理各类型佣金
     *
     * @param orderHead      处理的订单
     * @param hotelAccountId 处理的酒店id
     * @param cardNo         卡号
     * @param type           1卡酒店，2非卡酒店
     * @param flag           是否是运营商卖的卡(true是，false不是)
     */
    private void miniDisposeCommission(OrderHead orderHead, Integer hotelAccountId, String cardNo, String phone, Integer type, Boolean flag) {
        //1，酒店佣金入账
        if (1 == type) {
            miniAddCommission(orderHead, hotelAccountId, cardNo, phone, MiniVipCommissionBillTypeEnum.CARD_HOTEL.value(), flag);
        } else {
            miniAddCommission(orderHead, hotelAccountId, cardNo, phone, MiniVipCommissionBillTypeEnum.NO_CARD_HOTEL.value(), flag);
        }
        //2，运营商佣金入账
        HotelDeveloperRelation developerRelation = hotelDeveloperRelationService.selectByAccountIdAndType(hotelAccountId, HotelDeveloperRelationTypeEnum.OPERATOR.value(), 2);
        if (null != developerRelation) {
            if (1 == type) {
                miniAddCommission(orderHead, developerRelation.getDeveloperId(), cardNo, phone, MiniVipCommissionBillTypeEnum.CARD_OPERATOR.value(), flag);
            } else {
                miniAddCommission(orderHead, developerRelation.getDeveloperId(), cardNo, phone, MiniVipCommissionBillTypeEnum.NO_CARD_OPERATOR.value(), flag);
            }
        } else {
            log.info("该酒店账户id没有对应的运营商hotelAccountId = {}", hotelAccountId);
        }
    }

    /**
     * 小vip发放佣金（由于之前的所有步骤都是为了查询，所以在orderAdd方法里添加事务即可）
     *
     * @param orderHead 处理的订单
     * @param accountId 写入佣金的账户id
     * @param cardNo    卡号
     * @param cardNo    卡对应用户手机号
     * @param type      分佣明细类型
     * @param flag      是否是运营商卖的卡(true是，false不是)
     */
    private void miniAddCommission(OrderHead orderHead, Integer accountId, String cardNo, String phone, Integer type, Boolean flag) {
        if (orderHead.getVipProfit() <= 0) {
            miniVipCommissionBillService.orderAdd(accountId, 0, orderHead.getOrderNo(), type, cardNo, phone);
        } else {
            Integer rate = getDefaultRate(type, flag);
            if (null == rate) {
                log.info("该类型佣金不存在type = {}, flag = {}", type, flag);
                return;
            }
            miniVipCommissionBillService.orderAdd(accountId,
                    FormatUtils.amountToRateV2(orderHead.getVipProfit(), rate), orderHead.getOrderNo(), type, cardNo, phone);
        }
    }

    /**
     * 查询默认的佣金比率
     * 卡是运营商卖的还是卡商卖的
     * 卡酒店20%，卡运营商7.5%，卡酒店20%，卡运营商7.5%
     *
     * @param type 类型 1:卡酒店 2:卡运营商 5:非卡酒店 6:非卡运营商 9：卡商
     * @param flag true运营商卖的，false卡商卖的
     * @return
     */
    private Integer getDefaultRate(Integer type, Boolean flag) {
        if (flag) {
            switch (type) {
                case 1:
                case 5:
                    return 2000;
                case 2:
                case 6:
                    return 1000;
                default:
                    return null;
            }

        } else {
            switch (type) {
                case 1:
                case 5:
                    return 2000;
                case 2:
                case 6:
                    return 750;
                case 9:
                    return 500;
                default:
                    return null;
            }
        }
    }
}
